package com.weihe.toolkit.file;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;

public class FileToolkit {
	
	public static String getExtensionName(String filename) {   
        if ((filename != null) && (filename.length() > 0)) {   
            int dot = filename.lastIndexOf('.');   
            if ((dot >-1) && (dot < (filename.length() - 1))) {   
                return filename.substring(dot + 1);   
            }   
        }   
        return filename;   
	}
	
	public static boolean createFolder(String filePath) {
		
		if(StringUtils.isNotBlank(filePath)){
			filePath = filePath.trim();
			File myFilePath = new File(filePath);
			try {
				if(!myFilePath.exists()){
					myFilePath.mkdirs();
				}
				return true;
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
		}
		
		throw new NullPointerException("file path is blank");

	}
	
	public static boolean isInSubDirectory(String parentPath, String subPath) {
		
		if(StringUtils.isNotBlank(parentPath) && StringUtils.isNotBlank(subPath)){
			File p = new File(parentPath.trim());
			File s = new File(subPath.trim());
			if(p.exists() && s.exists()){
				while(null != s.getParentFile()){
					s = s.getParentFile();
					if(StringUtils.equals(p.getAbsolutePath(), s.getAbsolutePath())){
						return true;
					}
				}
			}
			return false;
		}
		throw new NullPointerException("file path is blank");

	}
	
	public static boolean isSameDirectory(String path, String apath) {
		
		if(StringUtils.isNotBlank(path) && StringUtils.isNotBlank(apath)){
			File p = new File(path.trim());
			File s = new File(apath.trim());
			if(p.exists() && s.exists()){
				if(StringUtils.equals(p.getAbsolutePath(), s.getAbsolutePath())){
					return true;
				}
			}
			return false;
		}
		throw new NullPointerException("file path is blank");
		
	}
	
	
	public static void main(String[] args) {
		File f = new File("d:");
		File fs = new File("d:\\pic\\cloudauth\\..");
		File t = fs.getParentFile();
		System.out.println(FileToolkit.isInSubDirectory("d:", "d:\\pic\\..\\"));
		System.out.println("="+f.getAbsolutePath()+"="+fs.getAbsolutePath()+"="+t.getAbsolutePath());
		String[] list = t.list();
		for(String str : list){
			System.out.println(str);
		}
	}
	
	
	public static boolean writeToFile(String fileName, String content, boolean append) throws IOException {
		boolean result = false;
		if(StringUtils.isNotBlank(fileName)&& null != content){
			File file = new File(fileName);
			if (!file.exists()) {
				file.createNewFile();
			}
			FileWriter fw = null;
			BufferedWriter bw = null;
			try {
				fw = new FileWriter(file, append);
				bw = new BufferedWriter(fw);
				bw.write(content);
			} finally {
				if (null != bw) {
					bw.close();
				}
				if (null != fw) {
					fw.close();
				}
			}
			result = true;
		}		
		return result;
	}
	
	public static boolean writeToFile(String fileName, String content) throws IOException {
		return writeToFile(fileName, content, false);
	}
	
	public static boolean writeToFile(String fileName, List<String> listString) throws IOException {
		StringBuilder sb = new StringBuilder();
		if(null != listString){
			for(String str: listString){
				sb.append(str+"\r\n");
			}
		}
		return writeToFile(fileName, sb.toString(), false);
	}
	
	public static boolean appendToFile(String fileName, String content) throws IOException {
		return writeToFile(fileName, content, true);
	}
	
	public static boolean writeToFile(String filePathAndName, byte[] content) throws IOException {
		boolean result = false;
		if(StringUtils.isNotBlank(filePathAndName)&& null != content){
			File file = new File(filePathAndName);
			if (!file.exists()) {
				file.createNewFile();
			}
			BufferedOutputStream bw = null;
			try {
				bw = new BufferedOutputStream(new FileOutputStream(filePathAndName));
				bw.write(content);
			} finally {
				if (null != bw) {
					bw.close();
				}
			}
			result = true;
		}		
		return result;
	}
	
	public static boolean existFile(String filePath){
		File file = new File(filePath);
		return file.exists();
	}
	
	public static boolean createFile(String filePath){
		if(StringUtils.isNotBlank(filePath)){
			filePath = filePath.trim();
			File file = new File(filePath);
			createFolder(file.getParent());
			if(!file.exists()){
				try {
					return file.createNewFile();
				} catch (IOException e) {
					e.printStackTrace();
					return false;
				}
			}
			return true;
		}
		throw new NullPointerException("file path is blank");
	}
	
	public static boolean delFile(String filePathAndName) {
		boolean bea = false;
		try {
			File myDelFile = new File(filePathAndName);
			if (myDelFile.exists()) {
				myDelFile.delete();
				bea = true;
			} else {
				bea = false;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bea;
	}

	public static boolean delFolerAllFile(String filePath) {
		boolean bea = false;
		File file = new File(filePath);
		if (!file.exists()) {
			return bea;
		}
		if (!file.isDirectory()) {
			return bea;
		}
		String[] tempList = file.list();
		File temp = null;
		for (int i = 0; i < tempList.length; i++) {
			if (filePath.endsWith(File.separator)) {
				temp = new File(filePath + tempList[i]);
			} else {
				temp = new File(filePath + File.separator + tempList[i]);
			}
			if (temp.isFile()) {
				temp.delete();
			}
			if (temp.isDirectory()) {
				delFolerAllFile(filePath + "/" + tempList[i]);
				delFile(filePath + "/" + tempList[i]);
				bea = true;
			}
		}
		bea = file.delete();
		return bea;

	}
	
	public static File[] listFolderFiles(String filePath) {
		try {
			File file = new File(filePath);
			if (file.exists()) {
				return file.listFiles();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	public static File[] listFolderFiles(String filePath,final String filter) {
		try {
			FileFilter f = new FileFilter(){
				public boolean accept(File pathname) {
					if(StringUtils.isNotBlank(filter)){
						if(pathname.getName().toLowerCase().endsWith(filter.toLowerCase())){
							return true;
						}else{
							return false;
						}
					}
					return true;
				}
				
			};
			File file = new File(filePath);
			if (file.exists()) {
				return file.listFiles(f);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	public static List<File> listFoldersAndFiles(final String filePath, String[] acceptExtensionNames) {
		File[] fs = listFolderFiles(filePath, null);
		if(null != fs && fs.length > 0){
			List<File> list = new ArrayList<File>();
			for(File f : fs){
				if(f.isDirectory()){
					list.add(f);
				}else if(f.isFile()){
					if(null != acceptExtensionNames && acceptExtensionNames.length>0){
						for(String en : acceptExtensionNames){
							if(StringUtils.equals(getExtensionName(f.getName().toUpperCase()),en.toUpperCase())){
								list.add(f);
							}
						}
					}
				}
			}
			return list;
		}
		return null;
	}
	
	public static List<String> display(File[] fs) {
		if(null == fs){
			return null;
		}
		List<String> list = new ArrayList<String>();
        for (int i = 0; i < fs.length; i++) {    
            if(fs[i].isFile())    
                list.add(fs[i].getName());    
        }
        return list;
    }
	
	/**
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	public static byte[] readByteContentFromFile(String filePath) throws IOException{
		byte[] input = null;
		if(StringUtils.isNotBlank(filePath)){
			FileInputStream in=new FileInputStream(filePath);
			input = new byte[in.available()];
			in.read(input);
			in.close();
		}
		return input;
	}
	
	public static String readStringContentFromFile(String filePath)
			throws IOException {
		byte[] input = readByteContentFromFile(filePath);
		if (null != input) {
			return new String(input);
		} else {
			return null;
		}
	}
	
	public static List<String> readStringByLines(String fileName) {
        File file = new File(fileName);
        BufferedReader reader = null;
        List<String> list = new ArrayList<String>();
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempString = null;
            while ((tempString = reader.readLine()) != null) {
                list.add(tempString);
            }
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                }
            }
        }
        return list;
    }
	
	public static List<String> readStringByLines(String fileName,int from, int to) {
		File file = new File(fileName);
		BufferedReader reader = null;
		List<String> list = new ArrayList<String>();
		if(from >= 0 && to >= from){
			try {
				int current = 1;
				reader = new BufferedReader(new FileReader(file));
				String tempString = null;
				while ((tempString = reader.readLine()) != null) {
					if(current >= from){
						list.add(tempString);
					}
					if(current >= to){
						break;
					}
					current++;
				}
				reader.close();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (reader != null) {
					try {
						reader.close();
					} catch (IOException e1) {
					}
				}
			}
		}
		
		return list;
	}
	
	
	/**
	 * 类和文件所在目录相同
	 * @param cls 
	 * @param fileName
	 * @return
	 * @throws IOException
	 */
	public static String getPathFromClass(Class cls,String fileName) throws IOException {
		String path = getPathFromClass(cls);
		if(null !=path){
			int i = path.lastIndexOf("/");
			if(i>=0){
				path = path.substring(0,i+1);
			}
			return path+fileName;
		}else{
			return null;
		}
		
	}

	public static String getPathFromClass(Class cls) throws IOException {
		String path = null;
		if (cls == null) {
			throw new NullPointerException();
		}
		URL url = getClassLocationURL(cls);
		if (url != null) {
			path = url.getPath();
			if ("jar".equalsIgnoreCase(url.getProtocol())) {
				try {
					path = "jar:"+new URL(path).toExternalForm();
				} catch (MalformedURLException e) {
				}
			}
		}
		return path;
	}


	public static URL getClassLocationURL(final Class cls) {
		if (cls == null) {
			throw new IllegalArgumentException("class that input is null");
		}
		URL result = null;
		final String clsAsResource = cls.getName().replace('.', '/')
				.concat(".class");
		final ProtectionDomain pd = cls.getProtectionDomain();
		if (pd != null) {
			final CodeSource cs = pd.getCodeSource();
			if (cs != null) {
				result = cs.getLocation();

			}
			if (result != null) {
				if ("file".equals(result.getProtocol())) {
					try {
						if (result.toExternalForm().endsWith(".jar")
								|| result.toExternalForm().endsWith(".zip")) {
							result = new URL("jar:"
									.concat(result.toExternalForm())
									.concat("!/").concat(clsAsResource));
						} else if (new File(result.getFile()).isDirectory()) {
							result = new URL("file:"+result+clsAsResource);
						}
					} catch (MalformedURLException ignore) {
					}
				}
			}
		}

		if (result == null) {
			final ClassLoader clsLoader = cls.getClassLoader();
			result = clsLoader != null ? clsLoader.getResource(clsAsResource)
					: ClassLoader.getSystemResource(clsAsResource);
		}
		return result;
	}
}
